/**
 * @file crtsurfdata2.cpp
 * @author your name (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2024-04-19
 *
 * @copyright Copyright (c) 2024
 *
 */
#include <iostream>
#include "../../public/_public.h"
#include <vector>

CLogFile logfile;
// 站点参数存放结构体
struct st_stcode
{
    /* data */
    char provname[31]; // 省
    char obtid[11];    // 站号
    char obtname[31];  // 站名
    double lat;        // 纬度
    double lon;        // 经度
    double height;     // 海拔高度
};

/**
 * @brief 加载站点参数
 *
 * @param inifile 站点参数文件，建议使用绝对路径
 * @return true
 * @return false
 */
// 把站点参数文件中加载到vstcode容器中。
bool LoadSTCode(const char *inifile);

int main(int argc, char *argv[])
{

    // 参>4
    if (argc != 4)
    {
        // 不能
        printf("Example: ./crtsurfdata1 inifile outpath logfile\n");
        printf("Example: ./crtsurfdata1 stcode.ini ./out log.txt\n");

        printf("inifile: 全国气象站点的参数，站点的位置\n");
        printf("outpath: 站点数据生成的位置\n");
        printf("inifile: 日志位置\n");
        return -1;
    }

    // 日志文件写东西。打开日志
    if (logfile.Open(argv[3], "a+", false))
    {
        // 写日志
        logfile.Write("第一次记录日志\n");
        logfile.WriteEx("第一次记录日志\n");

        if (LoadSTCode(argv[1]))
        {
            std::cout<<"加载完成\n"<<std::endl;
        }
        else
        {
            std::cout<<"加载失败\n"<<std::endl;
        }
    }
    else
    {
        // 日志失败
        printf("打开日志失败");
        return -1;
    }

    return 0;
}

bool LoadSTCode(const char *inifile)
{
    // 首先打开这个文件
    // 循环读
    // 分割
    // 写入一个结构体
    // 结构体存放到vector

    CFile File;
    CCmdStr CmdStr;
    struct st_stcode stcode;

    if (File.Open(inifile, "r"))
    {
        char strBuffer[301];
        memset(strBuffer, 0, 301);
        std::vector<struct st_stcode> vstcode;

        // 初始化
        while (true)
        {
            // 读取，检查是否退出
            if (File.Fgets(strBuffer,300,true))
            {
                // 切割字符串strBuffer,','和“,”
                CmdStr.SplitToCmd(strBuffer, ",", true);
                if (CmdStr.CmdCount()!=6) continue;
                // 存放到机构提
                // bool GetValue(const int inum,char *value,const int ilen=0); // 字符串，ilen缺省值为0。
                
                CmdStr.GetValue(0, stcode.provname, 30); // 省
                CmdStr.GetValue(1, stcode.obtid, 10);    // 站号
                CmdStr.GetValue(2, stcode.obtname, 30);  // 站名
                CmdStr.GetValue(3, &stcode.lat);         // 纬度
                CmdStr.GetValue(4, &stcode.lon);         // 经度
                CmdStr.GetValue(5, &stcode.height);      // 海拔高度

                // 个人建议：用完之后，去清空，为下一次循环做准备
                logfile.Write(stcode.provname,stcode.obtid);
                vstcode.push_back(stcode);
                memset((void*)&stcode,0,sizeof(struct st_stcode));
                //memset((void*) &stcode,0,301);
                
            }
            else
            {
                // 日志
                // logfile.Write("读取站点参数数据失败\n");
                break;
            }
        }
        return true;
    }
    else
    {
        logfile.Write("读取站点参数数据失败\n");
        return false;
    }

}

// 定义状态
// 初始化状态
// while
// 当前时刻状态更新
// 求输出
// 历史状态更新一次循环重置中间状态
// 为下

// 检查是否退出递归
// 输出
// 为下一次递归做准备，设定好中间状态




/*
递归：其实是要为了下一次递归做准备，所以会把状态进行变化

状态：迭代过程中，会不断由之前状态更新的东西，携带了当前迭代层的信息
输出：由状态组成或者形成，要被记录的
中间状态变量：不需要传递到下一层的，只是用来辅助生成输出的


初始化
while
新状态更新
使用中间状态和新状态和历史状态输出
更新旧状态
恢复中间状态，下一次迭代做准备

*/
